package com.runa.monitor.platinterface.extend.httpSimilar.bjrl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.runa.monitor.comm.dto.newComm.AsynResult;
import com.runa.monitor.comm.dto.newComm.PanelVO;
import com.runa.monitor.comm.entity.CommPanel;
import com.runa.monitor.comm.entity.CommTemperaturepressure;
import com.runa.monitor.platinterface.mqtt.MqttUtil;
import com.runa.persistence.config.CommConfig;
import com.runa.monitor.platinterface.extend.third.pojo.TemperaturePressureCurrentData;
import com.runa.monitor.platinterface.platService.RepositoryService;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 通过设备型号自行维护唤醒周期
 */
@Component
@EnableScheduling
@Slf4j
@Order(999999)
public class SimilarNB implements CommandLineRunner {

    @Value("${similarNB.BJRL-Panel.enable:false}")
    private Boolean enableOfBJRL;

    @Value("${similarNB.BJRL-Panel.period:10}")
    private Long periodOfBJJN;

    @Value("${similarNB.LC-Panel.enable:false}")
    private Boolean enableOfLC;
    @Resource
    private CommConfig config;
    @Resource
    private RepositoryService repositoryService;

    private final ConcurrentHashMap<String, String> bJRLPanelConcurrentHashMap = new ConcurrentHashMap();
    private final ConcurrentHashMap<String, String> bJRLPanelPreConcurrentHashMap = new ConcurrentHashMap();

    public static void main(String[] args) {
        System.out.println(new Date(1700895709000L));
    }

    @Override
    public void run(String... args) throws Exception {
        log.info("SimilarNB CommandLineRunner Running---");
        if (enableOfBJRL) {
            ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
            scheduledExecutorService.scheduleAtFixedRate(this::bjrlExecute, 0, periodOfBJJN, TimeUnit.MINUTES);
        }
        if (enableOfLC) {
            ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
            scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    lcExecute();
                }
            }, 0, periodOfBJJN, TimeUnit.MINUTES);
        }

    }

    public void bjrlExecute() {
        log.info("-------------http bjrlExecute Scheduled 面板AND温压信息开始启动-------------");
        List<CommPanel> panelList = repositoryService.getListCommPanelByNodeModel("BJRL-Panel");
        if (panelList.size() > 0) {
            bjrl(panelList);
            log.info("-------------http Scheduled BJRL-Panel panelList size-------------" + panelList.size());
        }
        List<CommTemperaturepressure> commTemperaturepressures = repositoryService.getListCommTemperaturepressureByNodeModel();
        if (commTemperaturepressures.size() > 0) {
            bjrlTemPre(commTemperaturepressures);
            log.info("-------------http Scheduled BJRL-TemPre commTemperaturepressures size-------------" + panelList.size());
        }
        log.info("-------------http bjrlExecute Scheduled 面板AND温压信息结束-------------");
    }

    public void lcExecute() {
        log.info("-------------http Scheduled 面板信息开始启动-------------");
        List<CommPanel> panelListLC = repositoryService.getListCommPanelByNodeModel("LC-Panel");
        if (panelListLC.size() > 0) {
            lc(panelListLC);
            log.info("-------------http Scheduled LC-Panel panelList size-------------" + panelListLC.size());
        }
        log.info("-------------http Scheduled 面板信息结束-------------");
    }

////    @Scheduled(cron = "0 30 */2 * * ?")
//    @Scheduled(cron = "0 */5 * * * ?")
//    @Transactional
//    public void execute() {
//    }

    private void bjrlTemPre(List<CommTemperaturepressure> commTemperaturepressures) {
        log.info("######Beijing SimilarNB bjrlTemPre 开始执行抄温压######");
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
//                .authenticator((route, response) -> {
////                    String credential = Credentials.basic("admin", "public");
////                    return response.request().newBuilder().header("Authorization", credential).build();
//                    return response.request().newBuilder().header("token", BjrlConfig.getToken()).build();
//                })
                .build();
//        String requestUrl = BjrlConfig.getHttpServer() + "/api/sn/common/external/bjrl/weather/getWorkByMac";
        String requestUrl = BjrlConfig.getUrlOfTemPre();
//        log.debug("emq请求信息:" + requestUrl);
        log.info("Beijing SimilarNB bjrlTemPre 请求信息:" + requestUrl + "-----" + BjrlConfig.getToken());
//        Request request = new Request.Builder().url(requestUrl).build();
        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
        HashMap<String, Object> map = new HashMap<>();

        List<String> collect = commTemperaturepressures.stream().map(CommTemperaturepressure::getSerial).collect(Collectors.toList());
        while (collect.size() > 0) {//目前只能一次1个
            List<String> commPanels = new ArrayList<>();
            if (collect.size() > 1) {
                commPanels = collect.subList(0, 1);
                collect = collect.subList(1, collect.size());
            } else {
                commPanels = new ArrayList<>(collect);
                collect.clear();
            }
            map.put("codeList", commPanels);
//            String requestBodyStr = "{\"username\":\"example\",\"password\":\"123456\"}";
//        RequestBody requestBody = RequestBody.create(mediaType, requestBodyStr);
            String s = JSON.toJSONString(map);
            log.info("bjrlTemPre requestBody is" + s);
            RequestBody requestBody = RequestBody.create(s, mediaType);
            Request request = new Request.Builder().url(requestUrl).post(requestBody)
                    .addHeader("token", BjrlConfig.getToken())
                    .addHeader("Content-Type", "application/json; charset=utf-8").build();
            try {
                Response response = okHttpClient.newCall(request).execute();
                log.info("获取Beijing SimilarNB bjrlTemPre数据成功------" + response);
                if (response.isSuccessful() && response.body() != null) {
                    val responseString = Objects.requireNonNull(response.body()).string();
                    log.info("获取Beijing SimilarNB bjrlTemPre数据成功------" + responseString);
//                log.info("获取emq数据成功------" + responseString);
                    JSONObject jsonObject = JSONObject.parseObject(responseString);
                    if (!jsonObject.get("code").equals(200)) {
                        log.error("SimilarNB bjrlTemPre error" + JSON.toJSONString(response));
                        continue;
                    }
                    JSONArray data = jsonObject.getJSONArray("data");

                    JSONObject jsonObjectT = JSONObject.parseObject(data.get(0).toString());
                    String deviceId = jsonObjectT.get("tbNamePrefix").toString();
                    String collectTime = jsonObjectT.get("ts").toString();
                    //计量上次的采集时间
                    if (bJRLPanelPreConcurrentHashMap.get(deviceId) != null
                            && bJRLPanelPreConcurrentHashMap.get(deviceId).equalsIgnoreCase(collectTime)) {
                        continue;
                    } else {
                        bJRLPanelPreConcurrentHashMap.put(deviceId, collectTime);
                    }
                    Date date = new Date(Long.valueOf(collectTime));
                    TemperaturePressureCurrentData temperaturePressureCurrentData = new TemperaturePressureCurrentData();
                    temperaturePressureCurrentData.setReadTime(date);
//                        panelVO.setPanelDate(new Date());
                    temperaturePressureCurrentData.setSerial(deviceId);
                    for (Object datum : data) {
                        String name = JSONObject.parseObject(datum.toString()).get("tbNameSuffix").toString();
                        if (name.equalsIgnoreCase("back_temp")){
                            temperaturePressureCurrentData.setReturnTemp(Float.valueOf(JSONObject.parseObject(datum.toString()).get("val").toString()));
                        }else if (name.equalsIgnoreCase("go_temp")){
                            temperaturePressureCurrentData.setSupplyTemp(Float.valueOf(JSONObject.parseObject(datum.toString()).get("val").toString()));
                        }else if (name.equalsIgnoreCase("battery_level")){
                            temperaturePressureCurrentData.setBatteryVol(Float.valueOf(JSONObject.parseObject(datum.toString()).get("val").toString()));
                        }else if (name.equalsIgnoreCase("signal_strength")){
                            temperaturePressureCurrentData.setSignal(JSONObject.parseObject(datum.toString()).get("val").toString());
                        }
                    }
                    String back_temp = jsonObjectT.get("val").toString();
//                        Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(collectTime);
                    List<CommTemperaturepressure> commTemperaturepressuresT = commTemperaturepressures.stream().filter(commTemperaturepressure -> commTemperaturepressure.getSerial().equalsIgnoreCase(deviceId)).collect(Collectors.toList());
//                    temperaturePressureCurrentData.set(Float.valueOf(back_temp));
                    AsynResult asynResult = new AsynResult();
                    asynResult.successSetting();
                    asynResult.setContent((temperaturePressureCurrentData));
                    asynResult.setIdentity(commTemperaturepressuresT.get(0).getId());
                    MqttUtil.send(TemperaturePressureCurrentData.TOPIC, asynResult);
                } else {
                    if (response.body() != null) {
                        Objects.requireNonNull(response.body()).close();
                    }
                }
            } catch (Exception e) {
                log.error("Beijing SimilarNB bjrlTemPre 开始执行抄温压异常: ", e);
            }

        }
    }

    private void lc(List<CommPanel> panelList) {
        log.info("######lc SimilarNB 开始执行抄面板######");
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .authenticator((route, response) -> {
//                    String credential = Credentials.basic("admin", "public");
//                    return response.request().newBuilder().header("Authorization", credential).build();
//                    return response.request().newBuilder().header("token", BjrlConfig.getToken()).build();
                    return response.request().newBuilder().header("Access-Token", CommConfig.getToken()).build();
                })
                .build();
//        String requestUrl = BjrlConfig.getHttpServer() + "/api/sn/common/external/bjrl/weather/getWorkByMac";
        String requestUrl = config.getUrl();
//        log.debug("emq请求信息:" + requestUrl);
        log.info("lc SimilarNB 请求信息:" + requestUrl);
//        Request request = new Request.Builder().url(requestUrl).build();

        List<String> collect = panelList.stream().map(CommPanel::getSerial).collect(Collectors.toList());
        while (!collect.isEmpty()) {
            List<String> commPanels = collect.subList(0, 1);
            if (collect.size() == 1) {
                collect.clear();
            } else {
                collect = collect.subList(1, collect.size());
            }
//            map.put("macIdList", commPanels);
            requestUrl += "?deviceSn=" + commPanels.get(0);
//            String requestBodyStr = "{\"username\":\"example\",\"password\":\"123456\"}";
//        RequestBody requestBody = RequestBody.create(mediaType, requestBodyStr);
//            RequestBody requestBody = RequestBody.create(JSON.toJSONString(map), mediaType);
            Request request = new Request.Builder().url(requestUrl).get().build();
            try {
                Response response = okHttpClient.newCall(request).execute();
                log.debug("获取lc SimilarNB数据成功------" + response);
                if (response.isSuccessful() && response.body() != null) {
                    val responseString = Objects.requireNonNull(response.body()).string();
                    log.info("获取lc SimilarNB数据成功------" + responseString);
//                log.info("获取emq数据成功------" + responseString);
                    JSONObject jsonObject = JSONObject.parseObject(responseString);
                    if (!jsonObject.get("status").equals("SUCCESS")) {
                        log.error("lc SimilarNB error" + JSON.toJSONString(response));
                        continue;
                    }
//                    JSONArray data = jsonObject.getJSONArray("content");
//                    JSONObject lastReportData = JSONObject.parseObject("lastReportData");
//                    JSONObject lastReportData = JSONObject.parseObject(jsonObject.get("status").toString());
//                    JSONArray data = JSONObject.parseArray("rows");
                    JSONArray data = JSONObject.parseArray(jsonObject.getJSONObject("content").getJSONObject("lastReportData").get("rows").toString());
                    for (Object datum : data) {
                        JSONObject jsonObjectT = JSONObject.parseObject(datum.toString());
                        String deviceId = jsonObjectT.get("deviceId").toString();
                        String temperature = jsonObjectT.get("temperature").toString();
                        String humidity = jsonObjectT.get("humidity").toString();
                        String batteryVoltage = jsonObjectT.get("batteryVoltage").toString();
                        String signalCsq = jsonObjectT.get("signalCsq").toString();
//                        String reportTime = jsonObjectT.get("reportTime").toString();
//                        String collectedTime = jsonObjectT.get("collectedTime").toString();
//                        String collectTime = jsonObjectT.get("collectTime").toString();
                        List<CommPanel> panels = panelList.stream().filter(commPanel -> commPanel.getSerial().equalsIgnoreCase(deviceId)).collect(Collectors.toList());
                        PanelVO panelVO = new PanelVO();
                        panelVO.setReadTime(new Date());
                        panelVO.setPanelDate(new Date());
                        panelVO.setSerial(deviceId);
                        panelVO.setTemperature(Float.valueOf(temperature));
                        panelVO.setHumidity(Float.valueOf(humidity));
                        panelVO.setBatteryVol(Float.valueOf(batteryVoltage));
                        panelVO.setPanelDate(new Date());
                        panelVO.setReadTime(new Date());
//                        panelVO.setPanelDate((reportTime));
//                        panelVO.setReadTime(Float.valueOf(reportTime));

                        AsynResult asynResult = new AsynResult();
                        asynResult.successSetting();
                        asynResult.setContent(Collections.singleton(panelVO));
                        asynResult.setIdentity(panels.get(0).getId());
                        MqttUtil.send(PanelVO.TOPIC, asynResult);
                    }


////                CommNetService commNetService = commNetServiceRepository.findOne(Example.of(CommNetService.builder().name("AI控制器").build())).orElse(null);
//                    HashSet<String> set = new HashSet<>();
////                if (commNetService!=null)
//                    set = NetEqu.getOnLineEquMap("null");
//                    log.debug("获取getOnLineEquMap数据成功------" + JSON.toJSONString(set));
//                    HashSet<String> hashSet = new HashSet<>(set);
////                List<String> serialNoList = commNetEquipmentRepository.findCurrentDataByOnlineAndAi().stream().map(s -> (String) s.get("serialNo")).collect(Collectors.toList());
//                    for (Object datum : data) {
//                        JSONObject jsonObjectT = JSONObject.parseObject(datum.toString());
//                        String clientid = jsonObjectT.get("clientid").toString();
//                        if (clientid.startsWith("aigw_jy_")) clientid = clientid.replace("aigw_jy_", "");
//                        if (clientid.startsWith("aigw_mt_")) clientid = clientid.replace("aigw_mt_", "");
//                        if (clientid.startsWith("aigw_")) clientid = clientid.replace("aigw_", "");
//                        if (clientid.length() > 5 && Pattern.compile("[0-9]*").matcher(clientid).matches()) {
//                            if (!hashSet.contains(clientid)) {
//                                NetEqu.onlineEqu(clientid);
//                                MqttUtil.sendOnLineStateOfNoneContent(clientid, true);
//                            } else {
//                                hashSet.remove(clientid);
//                            }
////                        NetEqu netEqu = netEquDao.findnetEquBySerialNo(clientid, null);
////                        if (netEqu != null && !netEquCurrentDataDao.findCurrentDataByNetEquId(netEqu.getUniqueId()).getState())
////                            upService.updateNetData(netEqu, true);
//                        }
//                    }
//                    hashSet.forEach((s -> MqttUtil.sendOnLineStateOfNoneContent(s, false)));
//                    response.body().close();
                } else {
                    if (response.body() != null) {
                        Objects.requireNonNull(response.body()).close();
                    }
                }
            } catch (Exception e) {
                log.error("Beijing SimilarNB 开始执行抄面板异常: ", e);
            }

        }
    }

    private void bjrl(List<CommPanel> panelList) {
        log.info("######Beijing SimilarNB 开始执行抄面板######");
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
//                .authenticator((route, response) -> {
////                    String credential = Credentials.basic("admin", "public");
////                    return response.request().newBuilder().header("Authorization", credential).build();
//                    return response.request().newBuilder().header("token", BjrlConfig.getToken()).build();
//                })
                .build();
//        String requestUrl = BjrlConfig.getHttpServer() + "/api/sn/common/external/bjrl/weather/getWorkByMac";
        String requestUrl = BjrlConfig.getUrl();
//        log.debug("emq请求信息:" + requestUrl);
        log.info("Beijing SimilarNB 请求信息:" + requestUrl + "-----" + BjrlConfig.getToken());
//        Request request = new Request.Builder().url(requestUrl).build();
        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
        HashMap<String, Object> map = new HashMap<>();

        List<String> collect = panelList.stream().map(CommPanel::getSerial).collect(Collectors.toList());
        while (collect.size() > 0) {
            List<String> commPanels = new ArrayList<>();
            if (collect.size() > 500) {
                commPanels = collect.subList(0, 500);
                collect = collect.subList(500, collect.size());
            } else {
                commPanels = new ArrayList<>(collect);
                collect.clear();
            }
            map.put("macIdList", commPanels);
//            String requestBodyStr = "{\"username\":\"example\",\"password\":\"123456\"}";
//        RequestBody requestBody = RequestBody.create(mediaType, requestBodyStr);
            String s = JSON.toJSONString(map);
            log.info("requestBody is" + s);
            RequestBody requestBody = RequestBody.create(s, mediaType);
            Request request = new Request.Builder().url(requestUrl).post(requestBody)
                    .addHeader("token", BjrlConfig.getToken())
                    .addHeader("Content-Type", "application/json; charset=utf-8").build();
            try {
                Response response = okHttpClient.newCall(request).execute();
                log.info("获取Beijing SimilarNB数据成功------" + response);
                if (response.isSuccessful() && response.body() != null) {
                    val responseString = Objects.requireNonNull(response.body()).string();
                    log.info("获取Beijing SimilarNB数据成功------" + responseString);
//                log.info("获取emq数据成功------" + responseString);
                    JSONObject jsonObject = JSONObject.parseObject(responseString);
                    if (!jsonObject.get("code").equals(200)) {
                        log.error("SimilarNB error" + JSON.toJSONString(response));
                        continue;
                    }
                    JSONArray data = jsonObject.getJSONArray("data");
                    for (Object datum : data) {
                        JSONObject jsonObjectT = JSONObject.parseObject(datum.toString());
                        String deviceId = jsonObjectT.get("deviceId").toString();
                        String value = jsonObjectT.get("value").toString();
                        String collectTime = jsonObjectT.get("collectTime").toString();
                        Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(collectTime);
                        List<CommPanel> panels = panelList.stream().filter(commPanel -> commPanel.getSerial().equalsIgnoreCase(deviceId)).collect(Collectors.toList());
                        //计量上次的采集时间
                        if (bJRLPanelConcurrentHashMap.get(deviceId) != null
                                && bJRLPanelConcurrentHashMap.get(deviceId).equalsIgnoreCase(collectTime)) {
                            continue;
                        } else {
                            bJRLPanelConcurrentHashMap.put(deviceId, collectTime);
                        }
                        PanelVO panelVO = new PanelVO();
                        panelVO.setReadTime(date);
//                        panelVO.setPanelDate(new Date());
                        panelVO.setSerial(deviceId);
                        panelVO.setTemperature(Float.valueOf(value));

                        AsynResult asynResult = new AsynResult();
                        asynResult.successSetting();
                        asynResult.setContent(Collections.singleton(panelVO));
                        asynResult.setIdentity(panels.get(0).getId());
                        MqttUtil.send(PanelVO.TOPIC, asynResult);
                    }


////                CommNetService commNetService = commNetServiceRepository.findOne(Example.of(CommNetService.builder().name("AI控制器").build())).orElse(null);
//                    HashSet<String> set = new HashSet<>();
////                if (commNetService!=null)
//                    set = NetEqu.getOnLineEquMap("null");
//                    log.debug("获取getOnLineEquMap数据成功------" + JSON.toJSONString(set));
//                    HashSet<String> hashSet = new HashSet<>(set);
////                List<String> serialNoList = commNetEquipmentRepository.findCurrentDataByOnlineAndAi().stream().map(s -> (String) s.get("serialNo")).collect(Collectors.toList());
//                    for (Object datum : data) {
//                        JSONObject jsonObjectT = JSONObject.parseObject(datum.toString());
//                        String clientid = jsonObjectT.get("clientid").toString();
//                        if (clientid.startsWith("aigw_jy_")) clientid = clientid.replace("aigw_jy_", "");
//                        if (clientid.startsWith("aigw_mt_")) clientid = clientid.replace("aigw_mt_", "");
//                        if (clientid.startsWith("aigw_")) clientid = clientid.replace("aigw_", "");
//                        if (clientid.length() > 5 && Pattern.compile("[0-9]*").matcher(clientid).matches()) {
//                            if (!hashSet.contains(clientid)) {
//                                NetEqu.onlineEqu(clientid);
//                                MqttUtil.sendOnLineStateOfNoneContent(clientid, true);
//                            } else {
//                                hashSet.remove(clientid);
//                            }
////                        NetEqu netEqu = netEquDao.findnetEquBySerialNo(clientid, null);
////                        if (netEqu != null && !netEquCurrentDataDao.findCurrentDataByNetEquId(netEqu.getUniqueId()).getState())
////                            upService.updateNetData(netEqu, true);
//                        }
//                    }
//                    hashSet.forEach((s -> MqttUtil.sendOnLineStateOfNoneContent(s, false)));
//                    response.body().close();
                } else {
                    if (response.body() != null) {
                        Objects.requireNonNull(response.body()).close();
                    }
                }
            } catch (Exception e) {
                log.error("Beijing SimilarNB 开始执行抄面板异常: ", e);
            }

        }
    }


}
